#include <tulip/SystemDefinition.h> 
#include <tulip/PluginLister.h>
#include <tulip/PluginLibraryLoader.h>
#include <tulip/PluginLoaderTxt.h>
#include <tulip/TlpTools.h>

#include <fcntl.h>
#include <string>
#include <list>
#include <map>
#include <iostream>
using namespace std;
using namespace tlp;

typedef std::list<std::string> StringList;
typedef std::map<std::string, StringList> StringMap;

struct PluginInformationsCollector : public PluginLoader {

	virtual void loaded(const tlp::Plugin* info, const std::list< Dependency >&) {
		_directoryPlugins[_currentDirectory].push_back(info->name());
	}

	virtual void aborted(const std::string& plugin, const std::string& message) {
		std::cout << "failed to load plugin " << plugin << ": " << message << std::endl;
	}
	virtual void loading(const std::string&) {}
	virtual void finished(bool, const std::string&) {}
	virtual void start(const std::string&) {}

	string _currentDirectory;
	StringMap _directoryPlugins;
};

int main(int argc,char **argv) 
{
	string appDir = ".";

	// First we initialize Tulip with basic plugins to ensure dependencies consistency
	tlp::initTulipLib(appDir.c_str());
	tlp::TulipPluginsPath = appDir;
	//tlp::PluginLibraryLoader::loadPlugins();
	//tlp::PluginLister::checkLoadedPluginsDependencies(0);

	PluginInformationsCollector collector;
	PluginLister::currentLoader = &collector;
	PluginLibraryLoader::loadPluginLibrary("ogdfsugiyama.dll", &collector);
	PluginLibraryLoader::loadPluginLibrary("DotImport.dll", &collector);

	for(StringMap::iterator itr=collector._directoryPlugins.begin(); itr!=collector._directoryPlugins.end();++itr)
	{
		string dir = itr->first;
		StringList& plugins = itr->second;
		for(StringList::iterator plugin_itr=plugins.begin(); plugin_itr!=plugins.end(); ++plugin_itr)
		{
			string plugin = *plugin_itr;
			const Plugin& info = PluginLister::pluginInformation(plugin);

			cout<<"------------------------------------------"<<endl;
			cout<<"name:"<<plugin.c_str()<<endl;
			cout<<"path:"<<dir.c_str()<<endl;
			cout<<"category"<<info.category().c_str()<<endl;
			cout<<"author"<< info.author().c_str()<<endl;
			cout<<"date"<<info.date().c_str()<<endl;
			cout<<"desc"<< info.info().c_str()<<endl;
			cout<<"release"<<info.release().c_str()<<endl;
			cout<<"tulip"<<info.tulipRelease().c_str()<<endl;

			const std::list<Dependency>& deps = PluginLister::getPluginDependencies(info.name());
			cout<<"dependencies:"<<endl;
			for(std::list<Dependency>::const_iterator dep_it = deps.begin(); dep_it != deps.end(); ++dep_it) 
			{
				cout<<"\tname:"<<dep_it->pluginName.c_str()<<endl;
			}
			cout<<endl;
		}
	}
}
